package com.bj58.ecdata.calc.dbservice.dao;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Component;

import redis.clients.jedis.Tuple;

import com.bj58.ecdata.calc.dbservice.dao.consts.DaoConst;
import com.bj58.ecdata.calc.dbservice.dao.model.ClickModel;
import com.bj58.ecdata.exception.BusinessException;
import com.bj58.ecdata.redis.JedisX;
import com.bj58.ecdata.util.DateUtils;
import com.bj58.ecdata.util.NumberUtils;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * @author lichao
 *
 */
@Component
public class ClickDao extends BaseDao<ClickModel> {
	
	@Autowired(required = false)
	@Qualifier("cachePool_handler")
	protected JedisX cacheHandler;
	
	//联盟技术部数据库，存CPC点击数据
	@Autowired(required = false)
	@Qualifier("otherJdbcTemplate")
	protected NamedParameterJdbcTemplate otherJdbcTemplate;
	protected final Set<String> otherTableNameSet = Sets.newConcurrentHashSet();
	
	@Override
	public void afterPropertiesSet() throws Exception {
		super.afterPropertiesSet();
		String sql = "SHOW TABLES like '"+tableName+"%';";
		Map<String, String> paramsMap = null;
		if(this.otherJdbcTemplate != null){
			List<String> list = this.otherJdbcTemplate.queryForList(sql, paramsMap, String.class);
			otherTableNameSet.clear();
			otherTableNameSet.addAll(list);
		}
	}
	
	@Override
	public void save(ClickModel model) {
		try {
			super.save(model);
			if(this.otherJdbcTemplate != null){
				this.jdbc_insert_otherDB(model);
			}
		} catch (Exception e) {
			throw new BusinessException(e);
		}
	}
	
	
	/**
	 * [minTime,maxTime]
	 */
	public Set<Tuple> loadsDetail(int count, long minTime, long maxTime) {
		Set<Tuple> result = null;
		try {
			result = cacheHandler.zrevrangeByScoreWithScores(DaoConst.DETAILS_CLICK, minTime, maxTime, count);
		} catch (Exception e) {
			throw new BusinessException(e);
		}
		if (result != null)
			return result;
		else
			return Collections.emptySet();
	}

	public long loadsDetailsCount(long time) {
		return cacheHandler.zcount(DaoConst.DETAILS_CLICK, time, Long.MAX_VALUE);
	}

	public long clearDetailCacheData(long time) {
		try {
			return cacheHandler.zremrangeByScore(DaoConst.DETAILS_CLICK, 0, time);
		} catch (Exception e) {
			throw new BusinessException(e);
		}
	}

	public Set<Tuple> loadsTopList(String dimension, int count) {
		try {
			Set<Tuple> result = super.cacheLoadsAccZset(dimension, 0, count - 1);
			if (result != null)
				return result;
			else
				return Collections.emptySet();
		} catch (Exception e) {
			throw new BusinessException(e);
		}
	}

	public Map<String, Long> loadUnionMapByCityType(List<ClickModel> params) {
		try {
			Map<String, Long> union = Maps.newConcurrentMap();
			for (ClickModel param : params) {
				Map<String, String> map = super.cacheLoadMapDimension("cityType", param);
				for (Entry<String, String> entry : map.entrySet()) {
					String city = entry.getKey();
					Long pv = union.get(city);
					if (pv == null) {
						pv = 0l;
					}
					union.put(city, pv + NumberUtils.toLong(entry.getValue()));
				}
			}
			return union;
		} catch (Exception e) {
			throw new BusinessException(e);
		}
	}


	
	@Override
	protected String getCreateSQL() {
		 return "CREATE TABLE %s ("
			  +"`time` bigint(20) NOT NULL,"
			  +"`platform` int(4) NOT NULL,"
			  +"`bussline` varchar(20) NOT NULL DEFAULT '',"
			  +"`pv` bigint(11) NOT NULL,"
			  +"`cash` bigint(11) NOT NULL,"
			  +"`cost` bigint(11) NOT NULL,"
			  +"`custNum` bigint(11) NOT NULL,"
			  +"`cityType` int(11) NOT NULL,"
			  +"`city1Id` int(11) NOT NULL,"
			  +"`city1Name` varchar(50) NOT NULL DEFAULT '',"
			  +"`cate2Id` varchar(100) NOT NULL DEFAULT '',"
			  +"`cate2Name` varchar(100) NOT NULL DEFAULT '',"
			  +"KEY `time` (`time`)"
			  +") ENGINE=InnoDB DEFAULT CHARSET=utf8;";
	}

	

	protected ClickModel jdbc_insert_otherDB(ClickModel model) throws Exception {
		long time = (Long) primaryDimension.getReadMethod().invoke(model);
		String curTableName = String.format("%s_%s", this.tableName,DateUtils.dateFormat(time,"yyyyMMdd")); 
		boolean hasTable = otherTableNameSet.contains(curTableName);
		if(!hasTable)
		{ 
			synchronized (this.otherTableNameSet) {
				if(!otherTableNameSet.contains(curTableName)){
					String sql = String.format(createSQL, curTableName);
					Map<String, String> paramMap = null;
					this.otherJdbcTemplate.update(sql, paramMap);
					otherTableNameSet.add(curTableName);
				}
			}
		}
		String sql = String.format("insert ignore into %s (%s) values( %s )",curTableName, this.jdbcHelper.getColumns(),
				this.jdbcHelper.getInsert_bean_columns());
		int ret = this.otherJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(model));
		return ret > 0 ? model : null;
	}
	
}
